{- This file is part of irc-fun-bot.
 -
 - Written in 2015 by fr33domlover <fr33domlover@riseup.net>.
 -
 - ♡ Copying is an act of love. Please copy, reuse and share.
 -
 - The author(s) have dedicated all copyright and related and neighboring
 - rights to this software to the public domain worldwide. This software is
 - distributed without any warranty.
 -
 - You should have received a copy of the CC0 Public Domain Dedication along
 - with this software. If not, see
 - <http://creativecommons.org/publicdomain/zero/1.0/>.
 -}

module Network.IRC.Fun.Bot.Internal.Monad
    ( runSession
    , ask
    , asks
    , get
    , gets
    , put
    , modify
    )
where

import Network.IRC.Fun.Bot.Internal.Types

import qualified Control.Monad.Trans.RWS as RWS

-- | Run a bot session computation.
runSession :: BotEnv e s -> BotState s -> Session e s a -> IO a
runSession bot state session = do
    (a, _, _) <- RWS.runRWST (unSession session) bot state
    return a

-- | Fetch the value of the environment.
ask :: Session e s (BotEnv e s)
ask = Session RWS.ask

-- | Retrieve a function of the current environment.
asks :: (BotEnv e s -> a) -> Session e s a
asks = Session . RWS.asks

-- | Fetch the current value of the state within the monad.
get :: Session e s (BotState s)
get = Session RWS.get

-- | Get a specific component of the state, using a projection function
-- supplied.
gets :: (BotState s -> a) -> Session e s a
gets = Session . RWS.gets

-- | @'put' s@ sets the state within the monad to @s@.
put :: BotState s -> Session e s ()
put = Session . RWS.put

-- | @'modify' f@ is an action that updates the state to the result of
-- applying @f@ to the current state.
modify :: (BotState s -> BotState s) -> Session e s ()
modify = Session . RWS.modify
